package fr.lip6.meta.ple.generation.tools;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.PrintStream;
import java.util.ArrayList;

import artefact.umlClassDiagram.CreateAssociation;
import artefact.umlClassDiagram.CreateClass;
import artefact.umlClassDiagram.CreateGeneralization;
import artefact.umlClassDiagram.CreateOperation;
import artefact.umlClassDiagram.CreateOperationRefinement;
import artefact.umlClassDiagram.impl.CreateAttributeImpl;

import fr.lip6.meta.ple.featureIdentification.Feature;
import fr.lip6.meta.tools.StatementPrimitive;

/**
 * @author Simon Grandsire
 *
 */
public abstract class PLConstructionFactory {
	protected PrintFile printFile = null;
	
	/**
	 * @param stPrimitive
	 * @param feat
	 * @param classesName
	 * @return 
	 * @throws FileNotFoundException
	 */
	public abstract PrintStream createPackage(
			StatementPrimitive stPrimitive,
			Feature feat,
			ArrayList<String> classesName	) throws FileNotFoundException;
	
	/**
	 * @param crClass
	 * @param feat
	 * @param classesName TODO
	 * @return
	 * @throws FileNotFoundException
	 */
	public abstract PrintStream createClass(
			CreateClass crClass,
			Feature feat, ArrayList<String> classesName	) throws FileNotFoundException;
	
	/**
	 * @param crGen
	 * @param feat
	 * @param classesName TODO
	 * @return
	 * @throws FileNotFoundException
	 */
	public abstract PrintStream createGeneralization(
			CreateGeneralization crGen,
			Feature feat, ArrayList<String> classesName	) throws FileNotFoundException;
	
	/**
	 * @param crAttr
	 * @param feat
	 * @param classesName
	 * @return
	 * @throws FileNotFoundException
	 */
	public abstract PrintStream createAttribute(
			CreateAttributeImpl crAttr,
			Feature feat,
			ArrayList<String> classesName	) throws FileNotFoundException;
	
	/**
	 * @param crOp
	 * @param feat
	 * @param classesName
	 * @return
	 * @throws FileNotFoundException
	 */
	public abstract PrintStream createOperation(
			CreateOperation crOp,
			Feature feat,
			ArrayList<String> classesName	) throws FileNotFoundException;
	
	/**
	 * @param crOpRef
	 * @param feat
	 * @param classesName
	 * @return
	 * @throws FileNotFoundException
	 */
	public abstract PrintStream createOperationRefinement(
			CreateOperationRefinement crOpRef,
			Feature feat,
			ArrayList<String> classesName	) throws FileNotFoundException;
	
	/**
	 * @param crAsso
	 * @param feat
	 * @param classesName
	 * @return
	 * @throws FileNotFoundException
	 */
	public abstract PrintStream createAssociation(
			CreateAssociation crAsso,
			Feature feat,
			ArrayList<String> classesName	) throws FileNotFoundException;
	
	public PrintFile getPrintFile() {
		return printFile;
	}

	public void setPrintFile(PrintFile printFile) {
		this.printFile = printFile;
	}

	/**
	 * @author Simon Grandsire
	 *
	 */
	public class PrintFile {
		private StringBuilder stringBuilder;
		private File dotDir;
		private File dotFile;
		private FileOutputStream fout;
		private PrintStream out;

		public PrintFile(	StringBuilder stringBuilder,
							File dotDir,
							File dotFile,
							FileOutputStream fout,
							PrintStream out	) {
			this.stringBuilder = stringBuilder;
			this.dotDir = dotDir;
			this.dotFile = dotFile;
			this.fout = fout;
			this.out = out;
		}
		
		// getters and setters //
		
		public StringBuilder getStringBuilder() {
			return stringBuilder;
		}

		public File getDotDir() {
			return dotDir;
		}

		public File getDotFile() {
			return dotFile;
		}

		public FileOutputStream getFout() {
			return fout;
		}
		
		public PrintStream getOut() {
			return out;
		}
	}
}